/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有，侵权必究！
 */

package com.theme.passport.controller.app;

import com.theme.common.base.EmojiHandler;
import com.theme.common.base.JSONHandler;
import com.theme.common.base.PinYinUtils;
import com.theme.common.base.StringHandler;
import com.theme.common.frame.exception.ErrorCode;
import com.theme.common.mvc.utils.RedisKeys;
import com.theme.common.mvc.validator.ValidatorUtils;
import com.theme.common.mvc.view.R;
import com.theme.common.third.qq.QQHandler;
import com.theme.common.third.qq.bean.QQUserInfo;
import com.theme.common.third.wechat.WeixinHandler;
import com.theme.passport.annotation.Login;
import com.theme.passport.config.QQConfig;
import com.theme.passport.controller.app.utils.AppContextUtil;
import com.theme.passport.controller.app.utils.JwtUtils;
import com.theme.passport.controller.request.param.AesCbcUtil;
import com.theme.passport.dao.SysUserDao;
import com.theme.passport.entity.SysUserEntity;
import com.theme.passport.entity.SysUserTestEntity;
import com.theme.passport.entity.ThirdUserEntity;
import com.theme.passport.entity.UserEntity;
import com.theme.passport.entity.constant.UserOriginEnum;
import com.theme.passport.form.LoginCodeForm;
import com.theme.passport.form.LoginForm;
import com.theme.passport.form.QqLoginForm;
import com.theme.passport.form.WechatLoginForm;
import com.theme.passport.service.ThirdUserService;
import com.theme.passport.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;

/**
 * APP登录授权
 *
 * @author Mark sunlightcs@gmail.com
 */
@RestController
@RequestMapping("/app/login")
@Api("APP登录接口[密码登录，手机验证码登录，微信登录，QQ登录]")
public class AppLoginController {

    private static final Logger logger = LoggerFactory.getLogger(AppLoginController.class);

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private UserService userService;

    @Autowired
    private ThirdUserService thirdUserService;

    @Autowired
    private QQConfig qqConfig;

    @Resource(name = "redisTemplate")
    private ValueOperations<String, String> redisCache;

    @PostMapping("password")
    @ApiOperation("手机号密码登录")
    public R passwordLogin(@RequestBody LoginForm form) {
        //表单校验
        ValidatorUtils.validateEntity(form);

        //查询是否存在用户
        UserEntity user = userService.queryByMobile(form.getMobile());
        if (user == null){
            return R.error(ErrorCode.FORM_USER_USERNAME_ERROR.getCode(),"手机号不存在!");
        }

        //用户登录
        long userId = userService.login(form);
        user = userService.getById(userId);
        user.setPassword(null);
        user.setSalt(null);
        //生成token
        String token = jwtUtils.generateToken(userId);

        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());

        return R.ok(map);
    }

    @PostMapping("codeLogin")
    @ApiOperation("手机号验证码登录")
    public R codeLogin(@RequestBody LoginCodeForm form) {
        //表单校验
        ValidatorUtils.validateEntity(form);

        //校验验证码是否合适
        //校验验证码是否合适
        R r = validatorCode(form.getMobile(),form.getCode());
        if (!R.isOk(r)){
            return r;
        }

        //查询是否存在用户
        UserEntity user = userService.queryByMobile(form.getMobile());
        if (user == null){
            return R.error(ErrorCode.FORM_USER_USERNAME_ERROR.getCode(),"手机号不存在!");
        }

        user.setPassword(null);
        user.setSalt(null);
        //生成token
        String token = jwtUtils.generateToken(user.getId());

        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());

        return R.ok(map);
    }

    private R validatorCode(String mobile, String code) {

        String loginKey = RedisKeys.SEND_CODE.concat(mobile);
        String result = redisCache.get(loginKey);
        if (StringHandler.isEmpty(result)){
            return R.error(ErrorCode.FORM_USER_CODE_ERROR.getCode(),"验证码已过期");
        }
        if (result.equals(code)){
            return R.ok();
        }
        return R.error(ErrorCode.FORM_USER_CODE_ERROR.getCode(),ErrorCode.FORM_USER_CODE_ERROR.getMsg());
    }

    @GetMapping("wechatLogin")
    @ApiOperation("第三方登录[微信应用授权登录-暂无用]")
    public R wechatLogin(@Valid WechatLoginForm loginForm) {

        logger.info("微信小程序登录,参数为：{}", JSONHandler.getGson().toJson(loginForm));

        //表单校验
        ValidatorUtils.validateEntity(loginForm);

        // 到微信服务器获取openid和session_key
        Map loginInfo = WeixinHandler.getWebOAuth2AccessToken(loginForm.getCode());
        String objectToJson = JSONHandler.getGson().toJson(loginInfo);
        logger.info("appCallback ===> 微信授权后得到的用户信息为:{}",objectToJson);
        if (loginInfo == null) {
            return R.error("请求错误！");
        } else {
            Object obj = loginInfo.get("openid");
            if (obj == null){
                String errcode = loginInfo.get("errcode").toString();
                String errmsg = loginInfo.get("errmsg").toString();
                return R.error("错误码:["+errcode+"],错误信息:["+errmsg+"]");
            }
            String openid = loginInfo.get("openid").toString();
            String session_key = loginInfo.get("session_key").toString();
            //获取微信用户信息
            UserEntity user = null ;
            ThirdUserEntity thirdUserEntity = thirdUserService.queryByOpenid(UserOriginEnum.WECHAT.getValue(), openid);
            if (thirdUserEntity != null){
                user = userService.getById(thirdUserEntity.getUserId());
                return saveLoginInfo(user);
            }
            logger.info("获取微信用户信息,参数为openid：{},为空", openid);
            user = new UserEntity();
            try {
                //获取解密数据：
                String encryptedData = loginForm.getEncryptedData();
                String iv = loginForm.getIv();
                // 开始解密
                logger.info("获取解密微信用户信息,encryptedData：{},session_key：{},iv：{}", encryptedData, session_key, iv);
                String result = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8");
                logger.info("获取解密微信用户信息result:{}", result);
                if (null != result && result.length() > 0) {
                    JSONObject userInfoJSON = JSONObject.fromObject(result);
                    String nickname = EmojiHandler.filterEmoji(userInfoJSON.get("nickName").toString());
                    user.setNickname(nickname);
                    user.setUsername(PinYinUtils.getPingYin(nickname));
                    user.setAvatar(userInfoJSON.get("avatarUrl").toString());
                    user.setCountry(userInfoJSON.get("country").toString());
                    user.setProvince(userInfoJSON.get("province").toString());
                    user.setCity(userInfoJSON.get("city").toString());
                    user.setGender(Integer.valueOf(userInfoJSON.get("gender").toString()));
                    user.setOrigin(UserOriginEnum.WECHAT.getValue());
                    user.setOpenid(openid);
                    // 1、注册用户-微信
                    UserEntity resultUser = userService.registerUser(user);
                    // 2、保存用户登录信息
                    return saveLoginInfo(resultUser);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return R.ok();
    }

    @GetMapping("qqLogin")
    @ApiOperation("第三方登录[QQ应用授权登录-暂无用]")
    public R qqLogin(@Valid QqLoginForm loginForm) throws Exception{

        logger.info("QQ小程序登录,参数为：{}", JSONHandler.getGson().toJson(loginForm));

        //表单校验
        ValidatorUtils.validateEntity(loginForm);

        String accessToken = QQHandler.getAccessTokenByCode(qqConfig.getAppId(),qqConfig.getAppKey(),qqConfig.getRedirectUri(),loginForm.getCode());
        Map<String, String> qqInfo = QQHandler.getUserInfoByAccessToken(qqConfig.getAppId(), accessToken);

        // 到微信服务器获取openid和session_key
        if (StringHandler.isEmpty(qqInfo)) {
            logger.info("qq get user info ===== getUserInfo error");
            return R.error("请求错误！");
        } else {

            String qqUserjson = JSONHandler.getJsonStr(qqInfo);
            logger.info("qqCallback return qqUserInfo ===={}",qqUserjson);
            QQUserInfo qqUserInfo = JSONHandler.getObjectByJsonStr(qqUserjson, QQUserInfo.class);
            if (qqUserInfo == null){
                return R.error("请求错误！");
            }
            String openid = qqUserInfo.getOpenid();

            //获取微信用户信息
            UserEntity user = null ;
            ThirdUserEntity thirdUserEntity = thirdUserService.queryByOpenid(UserOriginEnum.QQ.getValue(), openid);
            if (thirdUserEntity != null){
                user = userService.getById(thirdUserEntity.getUserId());
                return saveLoginInfo(user);
            }
            try {
                logger.info("获取腾讯QQ用户信息,参数为openid：{},为空", openid);
                user = new UserEntity();
                user.setOrigin(UserOriginEnum.QQ.getValue());
                String nickname = EmojiHandler.filterEmoji(qqUserInfo.getNickname());
                user.setUsername(PinYinUtils.getPingYin(nickname));
                user.setNickname(nickname);
                user.setAvatar(qqUserInfo.getFigureurl_qq());
                user.setCountry(qqUserInfo.getCountry());
                user.setProvince(qqUserInfo.getProvince());
                user.setCity(qqUserInfo.getCity());
                user.setGender(Integer.valueOf(qqUserInfo.getGender()));
                user.setOrigin(UserOriginEnum.QQ.getValue());
                user.setOpenid(openid);
                // 1、注册用户-商户注册-微信注册
                UserEntity resultUser = userService.registerUser(user);
                // 2、保存用户登录信息
                return saveLoginInfo(resultUser);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return R.ok();
    }

    @Login
    @PostMapping("logout")
    @ApiOperation("用户退出登录")
    public R logout() {
        UserEntity currentUser = AppContextUtil.getCurrentUser();
        logger.info("用户[nickname:{}],退出登录!",currentUser.getNickname());
        return R.ok();
    }

    public R saveLoginInfo(UserEntity user) {
        if (user == null){
            return R.error("用户登录失败,请稍后重试!");
        }

        //生成token
        String token = jwtUtils.generateToken(user.getId());

        user.setPassword("");
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());
        map.put("user", user);

        return R.ok(map);
    }


    @Autowired
    private SysUserDao sysUserDao;

    @PostMapping("/userLoginTest")
    public R userLoginTest(String uname, String upwd) {
        Map m = new HashMap();
        List<SysUserTestEntity> userList = sysUserDao.userTest(uname, upwd);
        if (userList == null || userList.size() == 0) {
            m.put("code", 0);
            m.put("msg", "未找到用户，请确认账号密码是否正确");
        } else if (userList.size() > 1) {
            m.put("code", 1);
            m.put("msg", "存在多个用户，请联系管理员");
        } else {
            SysUserTestEntity userInfo = userList.get(0);
            Date currentDate = new Date(); // 当前时间
            Date specifiedDate = userInfo.getExpiresTime(); // 指定时间，这里是2022年11月1日
            Calendar currentCal = Calendar.getInstance();
            currentCal.setTime(currentDate);
            Calendar specifiedCal = Calendar.getInstance();
            specifiedCal.setTime(specifiedDate);
            if (specifiedCal.before(currentCal)) {
                m.put("code", 2);
                m.put("msg", "您的用户账户已过期，请续费或联系客服开通免费体验版");
            }else{
                m.put("code", 3);
                m.put("msg", "登录成功");

            }
        }
        return R.ok(m);
    }


    @PostMapping("/userRegTest")
    public R userRegTest(String uname, String upwd) {
        Map m = new HashMap();
        List<SysUserTestEntity> userList = sysUserDao.userTest(uname, upwd);
        if (userList == null || userList.size() == 0) {
            try{
                //注册
                sysUserDao.userregTest(uname,upwd);
                m.put("code", 0);
                m.put("msg", "注册成功");
            }catch (Exception e){
                m.put("code", 2);
                m.put("msg", "注册失败，请联系管理员");
            }
        } else if (userList.size() >= 1) {
            m.put("code", 1);
            m.put("msg", "该账户已被注册");
        }
        return R.ok(m);
    }
}
